package com.letu.core.utils;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class ClassObjectUtil {
    /**
     * 根据属性名获取属性值
     */
    public static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取属性名数组
     */
    public static String[] getFiledName(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String[] fieldNames = new String[fields.length];
        for (int i = 0; i < fields.length; i++) {
            fieldNames[i] = fields[i].getName();
        }
        return fieldNames;
    }

    /**
     * 获取属性类型(type)，属性名(name)，属性值(value)的map组成的list
     */
    public static List getFiledsInfo(String className, List list, Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        Map infoMap = null;
        for (int i = 0; i < fields.length; i++) {
            infoMap = new HashMap();
            if ("serialVersionUID".equals(fields[i].getName())) {
                continue;
            }
            //enum类不处理
            try{
                if("java.lang.Enum".equals(fields[i].getType().getSuperclass().getName())){
                    continue;
                }
            }catch (Exception e){

            }

            infoMap.put("type", fields[i].getType().toString());
            infoMap.put("name", StringUtils.isNoneBlank(className) ? className + "." + fields[i].getName() : fields[i].getName());
            infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
            //是否是基础属性
            if(!isBaseType(fields[i])){
                Object obj2 = null;
                try {
                    obj2 = Class.forName(fields[i].getType().getName()).newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                getFiledsInfo(StringUtils.isNoneBlank(className) ? className + "." + fields[i].getName() : fields[i].getName(), list, obj2);
            } else {
                list.add(infoMap);
            }

        }
        return list;
    }

    public static boolean isBaseType(Field field) {
        Class className = field.getType();
        if (className.equals(Integer.class) ||
                className.equals(Byte.class) ||
                className.equals(Long.class) ||
                className.equals(Double.class) ||
                className.equals(Float.class) ||
                className.equals(Character.class) ||
                className.equals(Short.class) ||
                className.equals(Boolean.class)
                || className.equals(java.util.Date.class)
                || className.equals(java.time.LocalDateTime.class)
                || className.equals(String.class)
        ) {
            return true;
        }
        return false;
    }

    /**
     * 获取属性类型(type)，属性名(name)，属性值(value)的map组成的list
     */
    public static List getChildFiledsInfo(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String[] fieldNames = new String[fields.length];
        List list = new ArrayList();
        Map infoMap = null;
        for (int i = 0; i < fields.length; i++) {
            infoMap = new HashMap();
            if ("serialVersionUID".equals(fields[i].getName())) {
                continue;
            }
            infoMap.put("type", fields[i].getType().toString());
            infoMap.put("name", fields[i].getName());
            infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
            list.add(infoMap);
        }
        return list;
    }

    /**
     * 获取对象的所有属性值，返回一个对象数组
     */
    public static Object[] getFiledValues(Object o) {
        String[] fieldNames = getFiledName(o);
        Object[] value = new Object[fieldNames.length];
        for (int i = 0; i < fieldNames.length; i++) {
            value[i] = getFieldValueByName(fieldNames[i], o);
        }
        return value;
    }

//    public static void main(String[] args) {
//        try {
//            List list = new ArrayList();
//            Object obj2 = Class.forName("com.letu.dynamicfrom.dto.Test1DTO").newInstance();
//            List s = new ClassObjectUtil().getFiledsInfo("", list, obj2);
//            System.out.println(JSON.toJSONString(s));
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//
//    }
}
